### @configure_input@

# Copyright (C) 2023-2024 Free Software Foundation, Inc.

# This file is part of GNU Emacs.

# GNU Emacs is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# GNU Emacs is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.

top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
srcdir = @srcdir@
builddir = @builddir@
version = @version@

# Don't install movemail if mailutils are to be used.
emacs_use_mailutils = @emacs_use_mailutils@

# This is the host lib-src and lib, not the cross compiler's lib-src.
libsrc = ../lib-src
EXEEXT = @EXEEXT@

-include ${top_builddir}/src/verbose.mk

SHELL = @SHELL@
JAVAC = @JAVAC@
AAPT = @AAPT@
D8 = @D8@
ZIPALIGN = @ZIPALIGN@
JARSIGNER = @JARSIGNER@
APKSIGNER = @APKSIGNER@
JARSIGNER_FLAGS =
ANDROID_JAR = @ANDROID_JAR@
ANDROID_ABI = @ANDROID_ABI@
ANDROID_SDK_18_OR_EARLIER = @ANDROID_SDK_18_OR_EARLIER@
ANDROID_SDK_8_OR_EARLIER = @ANDROID_SDK_8_OR_EARLIER@
WARN_JAVAFLAGS = @WARN_JAVAFLAGS@
JAVAFLAGS = $(WARN_JAVAFLAGS) -classpath "$(ANDROID_JAR):$(srcdir)"
FIND_DELETE = @FIND_DELETE@

# Android 4.3 and earlier require Emacs to be signed with a different
# digital signature algorithm.

ifneq (,$(ANDROID_SDK_18_OR_EARLIER))
JARSIGNER_FLAGS = -sigalg MD5withRSA -digestalg SHA1
else
JARSIGNER_FLAGS =
endif

# When building Emacs for Android 2.2, assets must not be compressed.
# Otherwise, the asset manager fails to extract files larger than 1
# MB.

ifneq (,$(ANDROID_SDK_8_OR_EARLIER))
AAPT_ASSET_ARGS = -0 ""
else
AAPT_ASSET_ARGS =
endif

SIGN_EMACS = -keystore $(srcdir)/emacs.keystore -storepass	\
	emacs1 $(JARSIGNER_FLAGS)
SIGN_EMACS_V2 = sign --v2-signing-enabled --ks			\
	$(srcdir)/emacs.keystore -debuggable-apk-permitted	\
	--ks-pass pass:emacs1

JAVA_FILES := $(wildcard $(srcdir)/org/gnu/emacs/*.java)
RESOURCE_FILES := $(foreach file,$(wildcard $(srcdir)/res/*),	\
		    $(wildcard $(file)/*))

# R.java is a file generated by the `aapt' utility containing
# constants that can then be used to locate ``resource identifiers''.
# It is not a regular file and should not be compiled as Java source
# code.  Instead, it is automatically included by the Java compiler.
RESOURCE_FILE := $(srcdir)/org/gnu/emacs/R.java

# CLASS_FILES is what should actually be built and included in the
# resulting Emacs executable.  The Java compiler might generate more
# than one class file for each source file, so this only serves as a
# list of dependencies for Make.
CLASS_FILES := $(foreach file,$(JAVA_FILES),$(basename $(file)).class)

# Remove RESOURCE_FILE from JAVA_FILES, if it is already present.
JAVA_FILES := $(filter-out $(RESOURCE_FILE),$(JAVA_FILES))

# Compute the name for the Emacs application package.  This should be:
# emacs-<version>-<min-sdk>-<abi>.apk

ANDROID_MIN_SDK := @ANDROID_MIN_SDK@
APK_NAME := emacs-$(version)-$(ANDROID_MIN_SDK)-$(ANDROID_ABI).apk

# How this stuff works.

# emacs.apk depends on emacs.apk-in, which is simply a ZIP archive
# containing the following files:
#  lib/$(ANDROID_ABI)/libemacs.so
#  lib/$(ANDROID_ABI)/libandroid-emacs.so
#  lib/$(ANDROID_ABI)/libctags.so
#  lib/$(ANDROID_ABI)/libetags.so
#  lib/$(ANDROID_ABI)/libhexl.so
#  lib/$(ANDROID_ABI)/libmovemail.so
#  lib/$(ANDROID_ABI)/librcs2log.so
#  lib/$(ANDROID_ABI)/libebrowse.so
#  assets/info/
#  assets/etc/
#  assets/lisp/

.PHONY: emacs.apk-in all
all: $(APK_NAME)

# Binaries to cross-compile.
CROSS_SRC_BINS := $(top_builddir)/cross/src/android-emacs
CROSS_LIBSRC_BINS := $(top_builddir)/cross/lib-src/ctags	\
		     $(top_builddir)/cross/lib-src/hexl		\
		     $(top_builddir)/cross/lib-src/ebrowse	\
		     $(top_builddir)/cross/lib-src/emacsclient	\
		     $(top_builddir)/cross/lib-src/etags
CROSS_LIBSRC_BINS_MOVEMAIL := $(top_builddir)/cross/lib-src/movemail
CROSS_EXEC_BINS := $(top_builddir)/exec/exec1 $(top_builddir)/exec/loader
CROSS_BINS = $(CROSS_SRC_BINS) $(CROSS_LIBSRC_BINS) $(CROSS_EXEC_BINS)

ifneq ($(emacs_use_mailutils),yes)
CROSS_LIBSRC_BINS := $(CROSS_LIBSRC_BINS) $(CROSS_LIBSRC_BINS_MOVEMAIL)
endif

# Libraries to cross-compile.
CROSS_LIBS = $(top_builddir)/cross/src/libemacs.so

# Make sure gnulib is built first!
# If not, then the recursive invocations of make below will try to
# build gnulib at the same time.
CROSS_ARCHIVES = $(top_builddir)/cross/lib/libgnu.a

# Third party libraries to compile.
-include $(top_builddir)/cross/ndk-build/ndk-build.mk

.PHONY: $(CROSS_BINS) $(CROSS_LIBS) $(CROSS_ARCHIVES)

# There should only be a single invocation of $(MAKE) -C
# $(top_srcdir)/cross for each directory under $(top_srcdir)/cross.
$(CROSS_SRC_BINS) $(CROSS_LIBS) &: $(CROSS_ARCHIVES)
	$(MAKE) -C $(top_builddir)/cross $(foreach file,	\
					   $(CROSS_SRC_BINS)	\
					   $(CROSS_LIBS),	\
					   src/$(notdir $(file)))

$(CROSS_LIBSRC_BINS) &: $(CROSS_ARCHIVES)
	$(MAKE) -C $(top_builddir)/cross $(foreach file,		\
					   $(CROSS_LIBSRC_BINS),	\
					   lib-src/$(notdir $(file)))

$(CROSS_ARCHIVES):
	$(MAKE) -C $(top_builddir)/cross lib/libgnu.a

# These two binaries are helpers used to execute binaries on Android
# 10 and later.

$(CROSS_EXEC_BINS) &:
	$(MAKE) -C $(top_builddir)/exec $(notdir $(CROSS_EXEC_BINS))

# This is needed to generate the ``.directory-tree'' file used by the
# Android emulations of readdir and faccessat.

$(libsrc)/asset-directory-tool:
	$(MAKE) -C $(libsrc) $(notdir $@)

# install_tmp is a directory used to generate emacs.apk-in.
# That is then packaged into $(APK_NAME).
# There is no need to depend on NDK_BUILD_SHARED as libemacs.so
# does already.

.PHONY: install_temp install_temp/assets/directory-tree
install_temp: $(CROSS_BINS) $(CROSS_LIBS) $(RESOURCE_FILES)
	$(AM_V_GEN)
# Make the working directory for this stuff
	$(AM_V_SILENT) rm -rf install_temp
	$(AM_V_SILENT) mkdir -p install_temp/lib/$(ANDROID_ABI)
	$(AM_V_SILENT) mkdir -p install_temp/assets/etc
	$(AM_V_SILENT) mkdir -p install_temp/assets/lisp
	$(AM_V_SILENT) mkdir -p install_temp/assets/info
# Install architecture independents to assets/etc and assets/lisp
	$(AM_V_SILENT) cp -r $(top_srcdir)/lisp install_temp/assets
	$(AM_V_SILENT) cp -r $(top_srcdir)/etc install_temp/assets
	$(AM_V_SILENT) cp -r $(top_srcdir)/info install_temp/assets
# Replace etc/DOC generated by compiling Emacs for the build machine
# with etc/DOC from the cross-compiled Emacs.
	$(AM_V_SILENT) test -f $(top_builddir)/cross/etc/DOC	\
	  && cp -r $(top_builddir)/cross/etc/DOC		\
	     install_temp/assets/etc
# Remove undesirable files from those directories.
	$(AM_V_SILENT)						\
	for subdir in `find install_temp -type d -print`; do	\
	  chmod a+rx $${subdir} ;				\
	  rm -rf $${subdir}/.gitignore ;			\
	  rm -rf $${subdir}/.DS_Store ;				\
	  rm -rf $${subdir}/#* ;				\
	  rm -rf $${subdir}/.#* ;				\
	  rm -rf $${subdir}/*~ ;				\
	  rm -rf $${subdir}/*.orig ;				\
	  rm -rf $${subdir}/ChangeLog* ;			\
	  rm -rf $${subdir}/[mM]akefile*[.-]in ;		\
	  rm -rf $${subdir}/Makefile;				\
	done
# Generate the directory tree for those directories.
# Install architecture dependents to lib/$(ANDROID_ABI).  This
# perculiar naming scheme is required to make Android preserve these
# binaries upon installation.
	$(AM_V_SILENT)								\
	for file in $(CROSS_BINS); do						\
	  if [ -x $$file ]; then      						\
	    filename=`basename $$file`; 					\
	    cp -f $$file install_temp/lib/$(ANDROID_ABI)/lib$${filename}.so;	\
	  fi 									\
	done
	$(AM_V_SILENT)						\
	for file in $(CROSS_LIBS); do				\
	  if [ -x $$file ]; then      				\
	    cp -f $$file install_temp/lib/$(ANDROID_ABI);	\
	  fi 							\
	done
# Next, produce a version of rcs2log befitting Android's naming
# conventions and shell interpreter location.
	$(AM_V_at) \
	sed 's|/bin/sh|/system/bin/sh|'					\
	 $(top_srcdir)/lib-src/rcs2log >				\
	 install_temp/lib/$(ANDROID_ABI)/librcs2log.so
	$(AM_V_at) chmod +x install_temp/lib/$(ANDROID_ABI)/librcs2log.so
ifneq ($(NDK_BUILD_SHARED),)
	$(AM_V_SILENT) cp -f $(NDK_BUILD_SHARED) \
	  install_temp/lib/$(ANDROID_ABI)
endif

install_temp/assets/directory-tree: $(libsrc)/asset-directory-tool \
  install_temp install_temp/assets/version 			   \
  install_temp/assets/build_info
	$(AM_V_GEN) $(libsrc)/asset-directory-tool install_temp/assets \
	  install_temp/assets/directory-tree

install_temp/assets/version: install_temp
	$(AM_V_GEN) { (cd $(top_srcdir)					\
			&& git rev-parse HEAD || echo "Unknown")	\
			&& (git rev-parse --abbrev-ref HEAD 		\
			    || echo "Unknown") } 2> /dev/null > $@

install_temp/assets/build_info: install_temp
	$(AM_V_GEN) { hostname; date +%s; } > $@

emacs.apk-in: install_temp install_temp/assets/directory-tree  \
  AndroidManifest.xml install_temp/assets/version	       \
  install_temp/assets/build_info
# Package everything.  Specifying the assets on this command line is
# necessary for AAssetManager_getNextFileName to work on old versions
# of Android.  Make sure not to generate R.java, as it's already been
# generated.
	$(AM_V_AAPT) $(AAPT) p -I "$(ANDROID_JAR)" -F $@   \
	  -f -M AndroidManifest.xml $(AAPT_ASSET_ARGS)	   \
	  -A install_temp/assets			   \
	  -S $(top_srcdir)/java/res -J install_temp
	$(AM_V_SILENT) pushd install_temp &> /dev/null;	\
	  $(AAPT) add ../$@ `find lib -type f`;		\
	popd &> /dev/null
	$(AM_V_SILENT) rm -rf install_temp

# Makefile itself.
.PRECIOUS: $(top_srcdir)/config.status Makefile
$(top_srcdir)/config.status: $(top_srcdir)/configure.ac $(top_srcdir)/m4/*.m4
	$(MAKE) -C $(dir $@) $(notdir $@)
Makefile: $(top_srcdir)/config.status $(top_srcdir)/java/Makefile.in
	$(MAKE) -C .. java/$@

# AndroidManifest.xml:
AndroidManifest.xml: $(top_srcdir)/configure.ac $(top_srcdir)/m4/*.m4 \
  $(srcdir)/AndroidManifest.xml.in
	pushd ..; ./config.status java/AndroidManifest.xml; popd

# R.java:
$(RESOURCE_FILE): $(RESOURCE_FILES)
	$(AM_V_GEN) $(AAPT) p -I "$(ANDROID_JAR)" -f	\
	  -J $(dir $@) -M AndroidManifest.xml		\
	  -S $(top_srcdir)/java/res

# Make all class files depend on R.java being built.
$(CLASS_FILES): $(RESOURCE_FILE)

.SUFFIXES: .java .class
$(CLASS_FILES) &: $(JAVA_FILES)
	$(AM_V_JAVAC) $(JAVAC) $(JAVAFLAGS) $(JAVA_FILES)
	$(AM_V_SILENT) touch $(CLASS_FILES)

# N.B. that find must be called all over again in case javac generated
# nested classes.

classes.dex: $(CLASS_FILES)
	$(AM_V_D8) $(D8) --classpath $(ANDROID_JAR)		\
	  $(subst $$,\$$,$(shell find $(srcdir) -type f		\
	    -name *.class)) --output $(builddir)

# When emacs.keystore expires, regenerate it with:
#
#  keytool -genkey -v -keystore emacs.keystore -alias "Emacs keystore" \
#   -keyalg RSA -sigalg  SHA1withRSA -keysize 2048 -validity 100000

.PHONY: clean maintainer-clean

$(APK_NAME): classes.dex emacs.apk-in $(srcdir)/emacs.keystore
	$(AM_V_GEN)
	$(AM_V_SILENT) cp -f emacs.apk-in $@.unaligned
	$(AM_V_SILENT) $(AAPT) add $@.unaligned classes.dex
	$(AM_V_SILENT) $(JARSIGNER) $(SIGN_EMACS) $@.unaligned "Emacs keystore"
	$(AM_V_SILENT) $(ZIPALIGN) -f 4 $@.unaligned $@
# Signing must happen after alignment!
	$(AM_V_SILENT) $(APKSIGNER) $(SIGN_EMACS_V2) $@
	$(AM_V_SILENT) rm -f $@.unaligned *.idsig

# TAGS generation.

ETAGS = $(top_builddir)/lib-src/etags

$(ETAGS): FORCE
	$(MAKE) -C ../lib-src $(notdir $@)

tagsfiles = $(JAVA_FILES) $(RESOURCE_FILE)

.PHONY: tags FORCE
tags: TAGS
TAGS: $(ETAGS) $(tagsfiles)
	$(AM_V_GEN) $(ETAGS) $(tagsfiles)

clean:
	rm -f *.apk emacs.apk-in *.dex *.unaligned *.class *.idsig
	rm -rf install-temp $(RESOURCE_FILE) TAGS
	find . -name '*.class' $(FIND_DELETE)

maintainer-clean distclean bootstrap-clean: clean
	rm -f Makefile ndk-build.mk
